package cn.lg.soar.boot.fc.service.impl;

import cn.lg.soar.boot.client.entity.ClientUser;
import cn.lg.soar.boot.client.service.ClientUserService;
import cn.lg.soar.boot.fc.entity.*;
import cn.lg.soar.boot.fc.entity.vo.RepairVo;
import cn.lg.soar.boot.fc.entity.vo.RoomVo;
import cn.lg.soar.boot.fc.entity.vo.TenancyRoomVo;
import cn.lg.soar.boot.fc.mapper.ContractMapper;
import cn.lg.soar.boot.fc.service.*;
import cn.lg.soar.common.algorithm.CryptoUtils;
import cn.lg.soar.common.data.msg.I18n;
import cn.lg.soar.common.model.HttpResult;
import cn.lg.soar.common.util.AssertUtil;
import cn.lg.soar.common.util.FileUtil;
import cn.lg.soar.common.util.data.RandomUtil;
import cn.lg.soar.database.base.service.impl.BaseServiceImpl;
import cn.lg.soar.database.query.SqueryWapper;
import cn.lg.soar.general.entity.FileMetadata;
import cn.lg.soar.general.manager.FileTemplateManager;
import cn.lg.soar.general.s3.FileTemplate;
import cn.lg.soar.general.service.IFileMetadataService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
public class StatServiceImpl implements StatService {

    @Autowired
    private FileTemplateManager uploadTemplateManager;
    @Autowired
    private TenancyRoomService tenancyRoomService;
    @Autowired
    private RoomService roomService;
    @Autowired
    private FinanceService financeService;
    @Autowired
    private RepairService repairService;
    @Autowired
    private CampusService campusService;
    @Autowired
    private BuildingService buildingService;
    @Autowired
    private UnitService unitService;
    @Autowired
    private FloorService floorService;
    @Autowired
    private FurnitureService furnitureService;
    /** 客户端用户信息服务 */
    @Autowired private ClientUserService clientUserService;


    /**
     * 楼栋统计
     */
    @Transactional
    public HttpResult<Map<String, Object>> buildingStat() {
        // 创建 QueryWrapper
        QueryWrapper<Building> queryWrapper = new QueryWrapper<>();
        // 使用 select 方法指定查询字段
        queryWrapper.select("SUM(area) as totalArea,SUM(use_area) as totalUseArea");
        // 执行查询
        List<Map<String, Object>> result = buildingService.listMaps(queryWrapper);

        BigDecimal totalArea = BigDecimal.ZERO;
        BigDecimal totalUseArea = BigDecimal.ZERO;
        // 获取结果
        if (result != null && !result.isEmpty()) {
            totalArea = BigDecimal.valueOf(((Number) result.get(0).get("totalArea")).intValue());
            totalUseArea = BigDecimal.valueOf(((Number) result.get(0).get("totalUseArea")).intValue());
        }

        LambdaQueryWrapper<Building> lambdaQueryWrapper = Wrappers.<Building>lambdaQuery();
        List<Building> list = buildingService.list(lambdaQueryWrapper);
        Map<String, Object> map = new HashMap<>();
        map.put("totalArea", totalArea);
        map.put("totalUseArea", totalUseArea);
        map.put("buildingCount", list.size());
        return HttpResult.data(map);
    }

    /**
     * 房间统计
     */
    @Transactional
    public HttpResult<Map<String, Object>> roomStat() {
        // 创建 QueryWrapper
        QueryWrapper<Room> queryWrapper = new QueryWrapper<>();
        // 使用 select 方法指定查询字段
        queryWrapper.select("SUM(area) as totalArea,SUM(use_area) as totalUseArea");
        // 执行查询
        List<Map<String, Object>> result = roomService.listMaps(queryWrapper);

        BigDecimal totalArea = BigDecimal.ZERO;
        BigDecimal totalUseArea = BigDecimal.ZERO;
        // 获取结果
        if (result != null && !result.isEmpty()) {
            totalArea = BigDecimal.valueOf(((Number) result.get(0).get("totalArea")).intValue());
            totalUseArea = BigDecimal.valueOf(((Number) result.get(0).get("totalUseArea")).intValue());
        }

        LambdaQueryWrapper<Room> lambdaQueryWrapper = Wrappers.<Room>lambdaQuery();
        List<Room> list = roomService.list(lambdaQueryWrapper);
        Map<String, Object> map = new HashMap<>();
        map.put("totalArea", totalArea);
        map.put("totalUseArea", totalUseArea);
        map.put("buildingCount", list.size());
        return HttpResult.data(map);
    }

    /**
     * 收费统计
     */
    @Transactional
    public HttpResult<Map<String, Object>> financeStat() {
        // 创建 QueryWrapper
        QueryWrapper<Finance> queryWrapper = new QueryWrapper<>();
        // 使用 select 方法指定查询字段
        queryWrapper.select("YEAR(pay_time) as payTimeYear, SUM(pay_amount) as payAmount, cost_type as costType");
        // 使用 groupBy 方法指定分组字段
        queryWrapper.groupBy("YEAR(pay_time), cost_type");
        // 执行查询
        List<Map<String, Object>> result = financeService.listMaps(queryWrapper);

        List<Integer> years = new ArrayList<>();
        List<BigDecimal> property = new ArrayList<>();
        List<BigDecimal> heating = new ArrayList<>();
        int currentYear = LocalDate.now().getYear();
        for (int i = 5; i >= 0; i--) {
            years.add(currentYear - i);
            BigDecimal propertyB = BigDecimal.valueOf(0);
            BigDecimal heatingB = BigDecimal.valueOf(0);
            for(Map<String, Object> map : result) {
                Integer costType = (Integer) map.get("costType");
//                Integer payTimeYear = (Integer) map.get("payTimeYear");
                if(map.get("payTimeYear") != null){
                    Integer payTimeYear = ((Number)map.get("payTimeYear")).intValue();
                    BigDecimal payAmount = BigDecimal.valueOf(((Number) map.get("payAmount")).intValue());
                    if(payTimeYear == currentYear - i){
                        if(costType == 2){
                            propertyB = payAmount;
                        }else if(costType == 5){
                            heatingB = payAmount;
                        }
                    }
                }
            }
            property.add(propertyB);
            heating.add(heatingB);
        }

        Map<String, Object> map = new HashMap<>();
        map.put("years", years);
        map.put("property", property);
        map.put("heating", heating);
        return HttpResult.data(map);
    }

    /**
     * 报修统计
     */
    @Transactional
    public HttpResult<Map<String, Object>> repairStat() {
        // 创建 QueryWrapper
        QueryWrapper<Repair> queryWrapper = new QueryWrapper<>();
        // 使用 select 方法指定查询字段
        queryWrapper.select("repair_state, COUNT(repair_state) AS repairStateCount");
        // 使用 groupBy 方法指定分组字段
        queryWrapper.groupBy("repair_state");
        // 执行查询
        List<Map<String, Object>> result = repairService.listMaps(queryWrapper);

        Integer repairStat0 = 0;
        Integer repairStat1 = 0;
        Integer repairStat2 = 0;
        for(Map<String, Object> map : result) {
            Integer repairState = (Integer) map.get("repair_state");
            Integer repairStateCount = ((Number)map.get("repairStateCount")).intValue();
            if(repairState == 0){
                repairStat0 = repairStateCount;
            }else if(repairState == 1){
                repairStat1 = repairStateCount;
            }else if(repairState == 2){
                repairStat2 = repairStateCount;
            }
        }

        Map<String, Object> map = new HashMap<>();
        map.put("repairStat0", repairStat0);
        map.put("repairStat1", repairStat1);
        map.put("repairStat2", repairStat2);
        map.put("repairStatSum", repairStat0+repairStat1+repairStat2);
        return HttpResult.data(map);
    }

    /**
     * 最新报修
     */
    @Transactional
    public HttpResult<RepairVo> newRepair() {
        // 创建 QueryWrapper
        QueryWrapper<Repair> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("repair_state", 0);
        queryWrapper.orderByDesc("repair_time");
        // 执行查询
        List<Repair> list = repairService.list(queryWrapper);

        RepairVo repairVo = new RepairVo();
        if(list != null && !list.isEmpty()) {
            BeanUtils.copyProperties(list.get(0), repairVo);
            RoomVo roomVo = roomService.getVoData(list.get(0).getRoomId());
            String roomInfo = "";
            if(roomVo != null) {
                roomInfo = roomVo.getCampusEasyVo().getName()+"*"+roomVo.getBuildingEasyVo().getName()+"*"+roomVo.getUnitEasyVo().getName()+"*"
                        +roomVo.getFloorEasyVo().getName()+"*"+roomVo.getRoomCode();
            }
            repairVo.setRoomInfo(roomInfo);
        }

        return HttpResult.data(repairVo);
    }

    /**
     * 基础数据统计
     */
    @Transactional
    public HttpResult<Map<String, Object>> baseDataStat() {
        int campusNums = 0;
        int buildingNums = 0;
        int unitNums = 0;
        int floorNums = 0;
        int roomNums = 0;
        int furnitureNums = 0;

        // 创建 QueryWrapper
        QueryWrapper<Campus> queryWrapperCampus = new QueryWrapper<>();
        // 使用 select 方法指定查询字段
        queryWrapperCampus.select("COUNT(*) AS campusCount");
        // 执行查询
        List<Map<String, Object>> resultCampus = campusService.listMaps(queryWrapperCampus);
        // 获取结果
        if (resultCampus != null && !resultCampus.isEmpty()) {
            campusNums = ((Number) resultCampus.get(0).get("campusCount")).intValue();
        }

        // 创建 QueryWrapper
        QueryWrapper<Building> queryWrapperBuilding = new QueryWrapper<>();
        // 使用 select 方法指定查询字段
        queryWrapperBuilding.select("COUNT(*) AS buildingCount");
        // 执行查询
        List<Map<String, Object>> resultBuilding = buildingService.listMaps(queryWrapperBuilding);
        // 获取结果
        if (resultBuilding != null && !resultBuilding.isEmpty()) {
            buildingNums = ((Number) resultBuilding.get(0).get("buildingCount")).intValue();
        }

        // 创建 QueryWrapper
        QueryWrapper<Unit> queryWrapperUnit = new QueryWrapper<>();
        // 使用 select 方法指定查询字段
        queryWrapperUnit.select("COUNT(*) AS unitCount");
        // 执行查询
        List<Map<String, Object>> resultUnit = unitService.listMaps(queryWrapperUnit);
        // 获取结果
        if (resultUnit != null && !resultUnit.isEmpty()) {
            unitNums = ((Number) resultUnit.get(0).get("unitCount")).intValue();
        }

        // 创建 QueryWrapper
        QueryWrapper<Floor> queryWrapperFloor = new QueryWrapper<>();
        // 使用 select 方法指定查询字段
        queryWrapperFloor.select("COUNT(*) AS floorCount");
        // 执行查询
        List<Map<String, Object>> resultFloor = floorService.listMaps(queryWrapperFloor);
        // 获取结果
        if (resultFloor != null && !resultFloor.isEmpty()) {
            floorNums = ((Number) resultFloor.get(0).get("floorCount")).intValue();
        }

        // 创建 QueryWrapper
        QueryWrapper<Room> queryWrapperRoom = new QueryWrapper<>();
        // 使用 select 方法指定查询字段
        queryWrapperRoom.select("COUNT(*) AS roomCount");
        // 执行查询
        List<Map<String, Object>> resultRoom = roomService.listMaps(queryWrapperRoom);
        // 获取结果
        if (resultRoom != null && !resultRoom.isEmpty()) {
            roomNums = ((Number) resultRoom.get(0).get("roomCount")).intValue();
        }

        // 创建 QueryWrapper
        QueryWrapper<Furniture> queryWrapperFurniture = new QueryWrapper<>();
        // 使用 select 方法指定查询字段
        queryWrapperFurniture.select("COUNT(*) AS furnitureCount");
        // 执行查询
        List<Map<String, Object>> resultFurniture = furnitureService.listMaps(queryWrapperFurniture);
        // 获取结果
        if (resultFurniture != null && !resultFurniture.isEmpty()) {
            furnitureNums = ((Number) resultFurniture.get(0).get("furnitureCount")).intValue();
        }

        Map<String, Object> map = new HashMap<>();
        map.put("campusNums", campusNums);
        map.put("buildingNums", buildingNums);
        map.put("unitNums", unitNums);
        map.put("floorNums", floorNums);
        map.put("roomNums", roomNums);
        map.put("furnitureNums", furnitureNums);
        return HttpResult.data(map);
    }

    /**
     * 最新租房
     */
    @Transactional
    public HttpResult<TenancyRoomVo> newTenancyRoom() {
        // 创建 QueryWrapper
        QueryWrapper<TenancyRoom> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("tenancy_state", 3);
        queryWrapper.orderByDesc("apply_time");
        // 执行查询
        List<TenancyRoom> list = tenancyRoomService.list(queryWrapper);

        TenancyRoomVo tenancyRoomVo = new TenancyRoomVo();
        if(list != null && !list.isEmpty()) {
            BeanUtils.copyProperties(list.get(0), tenancyRoomVo);
            RoomVo roomVo = roomService.getVoData(list.get(0).getRoomId());
            String roomInfo = roomVo.getCampusEasyVo().getName()+"*"+roomVo.getBuildingEasyVo().getName()+"*"+roomVo.getUnitEasyVo().getName()+"*"
                    +roomVo.getFloorEasyVo().getName()+"*"+roomVo.getRoomCode();
            tenancyRoomVo.setRoomInfo(roomInfo);

            ClientUser user = clientUserService.getById(list.get(0).getUserId());
            if(user != null) {
                tenancyRoomVo.setUserName(user.getUserName());
            }
            tenancyRoomVo.setArea(roomVo.getArea());
            tenancyRoomVo.setLivingRoom(roomVo.getLivingRoom());
            tenancyRoomVo.setOrient(roomVo.getOrient());
            tenancyRoomVo.setOwnershipCode(roomVo.getOwnershipCode());
            tenancyRoomVo.setContacts(roomVo.getContacts());
            tenancyRoomVo.setPhone(roomVo.getPhone());
        }

        return HttpResult.data(tenancyRoomVo);
    }

    /**
     * 租房统计
     */
    @Transactional
    public HttpResult<Map<String, Object>> tenancyRoomStat() {
        int alreadyNums = 0;
        int notNums = 0;

        // 创建 QueryWrapper
        QueryWrapper<TenancyRoom> queryWrapper1 = new QueryWrapper<>();
        // 使用 select 方法指定查询字段
        queryWrapper1.select("COUNT(*) AS alreadyNums");
        queryWrapper1.eq("use_state",2);
        // 执行查询
        List<Map<String, Object>> result1 = tenancyRoomService.listMaps(queryWrapper1);
        // 获取结果
        if (result1 != null && !result1.isEmpty()) {
            alreadyNums = ((Number) result1.get(0).get("alreadyNums")).intValue();
        }

        // 创建 QueryWrapper
        QueryWrapper<TenancyRoom> queryWrapper2 = new QueryWrapper<>();
        // 使用 select 方法指定查询字段
        queryWrapper2.select("COUNT(*) AS notNums");
        queryWrapper2.eq("use_state",0);
        // 执行查询
        List<Map<String, Object>> result2 = tenancyRoomService.listMaps(queryWrapper2);
        // 获取结果
        if (result2 != null && !result2.isEmpty()) {
            notNums = ((Number) result2.get(0).get("notNums")).intValue();
        }

        Map<String, Object> map = new HashMap<>();
        map.put("alreadyNums", alreadyNums);
        map.put("notNums", notNums);
        return HttpResult.data(map);
    }

}
